home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / EmacsTeX / emacs-patches / lisp / objc-mode-no-untabify.el next >
Encoding:
Text File  |  1992-03-16  |  46.6 KB  |  1,411 lines

  1. ;; Major mode for editing Objective-C programs.
  2. ;; The Objective-C-mode is an extension of the
  3. ;; default C-mode. Unfortunately there are many
  4. ;; hardcoded parts for EB SIGNAL use only. However
  5. ;; it can be changed.  (And has: changed for RDR
  6. ;; by Chris Walters.
  7. ;;
  8. ;; Author: Kenneth Persson (kenneth@eb.se)
  9. ;;         EB Signal AB, Stockholm, Sweden
  10. ;;
  11. ;; Modified by:
  12. ;;         Douglas Worthington,
  13. ;;         dougw@grebyn.com
  14. ;;
  15. ;; Brutally hacked by David Stutz
  16. ;;
  17. ;; Eric Bergerson re-vamped
  18. ;; indenetation spacing to be like c-mode's indentation
  19. ;;
  20. ;; This is version 3.02.
  21. ;;
  22. ;; Put this in your .emacs file if its not in site-init.el:
  23. ;;
  24. ;; (autoload 'objective-C-mode "yourLispCodeDirectory/objective-C-mode"
  25. ;;           "Objective-C mode" t nil)
  26. ;; (setq auto-mode-alist
  27. ;;       (append '(("\\.h$" . objective-C-mode)
  28. ;;    ("\\.m$" . objective-C-mode))
  29. ;;       auto-mode-alist))
  30.  
  31. (provide 'objective-C-mode)
  32.  
  33. (defun objective-C-mode-version ()
  34.   "3.03a")
  35.  
  36. (defun echo-objective-C-mode-version ()
  37.   (interactive)
  38.   (message (concat "Version "
  39.               (objective-C-mode-version)
  40.                  " of "
  41.                 mode-name
  42.                    " mode.")))
  43.  
  44. (defvar objective-C-interface-file-dir nil
  45.   "The directory where to put generated interface files")
  46.  
  47. (defvar objective-C-document-file-dir nil
  48.   "The directory where to put generated document files")
  49.  
  50. (defvar objective-C-mode-map nil
  51.   "*Keymap used in objective-C mode.")
  52. (if objective-C-mode-map
  53.     nil
  54.   (let ((map (make-sparse-keymap))) 
  55.     (define-key map "\C-cc"     'objective-C-mfile-header)
  56.     (define-key map "\C-ch"     'objective-C-hfile-header)   
  57.     (define-key map "\C-cp"     'objective-C-protocol)
  58.     (define-key map "\C-cf"     'objective-C-factory-method)
  59.     (define-key map "\C-cm"     'objective-C-instance-method)
  60.     (define-key map "\C-cl"     'objective-C-codelimit)
  61.     (define-key map "\C-c\C-m"  'objective-C-method-comment)
  62.     (define-key map "\C-c\C-cd" 'generate-Objective-C-documentation)
  63.     (define-key map "\C-c\C-ch" 'generate-Objective-C-hfile)   
  64.     (define-key map "\C-c?"     'describe-objective-C-mode)   
  65.     (define-key map "\C-ci"     'indent-region)
  66.     (define-key map "\C-ca"     'add-user-sign)
  67.     (define-key map "\C-cv"     'echo-objective-C-mode-version)
  68.     (define-key map "{"         'electric-objective-C-brace)
  69.     (define-key map "}"         'electric-objective-C-brace)
  70.     (define-key map ":"         'electric-objective-C-keyword-match)
  71.     (define-key map "\177"      'backward-delete-char)
  72.     (define-key map "\t"        'objective-C-indent-command)
  73.     (setq objective-C-mode-map map)))
  74.  
  75. (define-abbrev-table 'objective-C-mode-abbrev-table ())
  76. (defvar objective-C-mode-abbrev-table nil
  77.   "abbrevations to use in objective-c")
  78.  
  79. ;;      (append objective-C-mode-abbrev-table
  80. ;;      (list '("ryes" "return YES"      nil)
  81. ;;    '("ry"   "return YES"      nil)
  82. ;;    '("rno"  "return NO"       nil)
  83. ;;    '("rn"   "return NO"       nil)
  84. ;;    '("rs"   "return self"     nil)
  85. ;;    '("rnil" "return nil"      nil)
  86. ;;    '("imp"  "@implementation" nil)
  87. ;;    '("intf" "@interface"      nil)
  88. ;;    '("slef" "self"            nil)
  89. ;;    '("st"   "STR"             nil)
  90. ;;    '("bo"   "BOOL"            nil))))
  91.  
  92. (defvar objective-C-mode-syntax-table nil
  93.   "Syntax table in use in Objective-C-Mode buffers.")
  94. (if objective-C-mode-syntax-table
  95.     nil
  96.   (setq objective-C-mode-syntax-table (make-syntax-table))
  97.   (modify-syntax-entry ?\\ "\\" objective-C-mode-syntax-table)
  98.   (modify-syntax-entry ?/ ". 14" objective-C-mode-syntax-table)
  99.   (modify-syntax-entry ?* ". 23" objective-C-mode-syntax-table)
  100.   (modify-syntax-entry ?+ "." objective-C-mode-syntax-table)
  101.   (modify-syntax-entry ?- "." objective-C-mode-syntax-table)
  102.   (modify-syntax-entry ?= "." objective-C-mode-syntax-table)
  103.   (modify-syntax-entry ?% "." objective-C-mode-syntax-table)
  104.   (modify-syntax-entry ?< "." objective-C-mode-syntax-table)
  105.   (modify-syntax-entry ?> "." objective-C-mode-syntax-table)
  106.   (modify-syntax-entry ?& "." objective-C-mode-syntax-table)
  107.   (modify-syntax-entry ?| "." objective-C-mode-syntax-table)
  108.   (modify-syntax-entry ?\' "\"" objective-C-mode-syntax-table)
  109.   (modify-syntax-entry ?: "_" objective-C-mode-syntax-table))
  110.  
  111. ;; Dave Stutz indentation numbers
  112. ;;
  113. ;;(defconst objective-C-indent-level 4
  114. ;;  "*Indentation of C statements with respect to containing block.")
  115. ;;(defconst objective-C-brace-imaginary-offset 0
  116. ;;  "*Imagined indentation of a C open brace that actually follows a statement.")
  117. ;;(defconst objective-C-brace-offset -4
  118. ;;  "*Extra indentation for braces, compared with other text in same context.")
  119. ;;(defconst objective-C-argdecl-indent 5
  120. ;;  "*Indentation level of declarations of C function arguments.")
  121. ;;(defconst objective-C-label-offset -4
  122. ;;  "*Offset of C label lines and case statements relative to usual indentation.")
  123. ;;(defconst objective-C-continued-statement-offset 4
  124. ;;  "*Extra indent for lines not starting new statements.")
  125.  
  126.  
  127. ;; Eric Bergerson indentation numbers
  128. ;;
  129. (defconst objective-C-indent-level 2
  130.   "*Indentation of C statements with respect to containing block.")
  131. (defconst objective-C-brace-imaginary-offset 0
  132.   "*Imagined indentation of a C open brace that actually follows a statement.")
  133. (defconst objective-C-brace-offset -2
  134.   "*Extra indentation for braces, compared with other text in same context.")
  135. (defconst objective-C-argdecl-indent 5
  136.   "*Indentation level of declarations of C function arguments.")
  137. (defconst objective-C-label-offset -2
  138.   "*Offset of C label lines and case statements relative to usual indentation.")
  139. (defconst objective-C-continued-statement-offset 2
  140.   "*Extra indent for lines not starting new statements.")
  141. (defconst objective-C-auto-newline nil
  142.   "*Non-nil means automatically newline before and after braces,
  143. and after colons and semicolons, inserted in C code.")
  144. (defconst objective-C-tab-always-indent t
  145.   "*Non-nil means TAB in C mode should always reindent the current line,
  146. regardless of where in the line point is when the TAB command is used.")
  147.  
  148. (defun objective-C-mode ()
  149.   "  A major mode for the Objective-C language.
  150. Commands:
  151.   Expression and list commands understand all Objective-C brackets.
  152.   Tab anywhere on a line indents it according to Objective-C
  153.   conventions. LF does a CR and then an indentation like above.
  154.   Comments are delimited with /* ... */ or // to cr.
  155.   Paragraphs are separated by blank lines only.
  156.   Delete converts tabs to spaces as it moves back.
  157. \\{objective-C-mode-map}
  158.  
  159. Variables controlling indentation style:
  160.   objective-C-indent-level
  161.     Indentation of C statements within surrounding block.
  162.     The surrounding block's indentation is the indentation
  163.     of the line on which the open-brace appears.
  164.  
  165. Variables controlling directories of generated files:
  166.     objective-C-interface-file-dir
  167.       If non nil generated interface files will be put into
  168.       this directory. The default is current directory.
  169.     objective-C-document-file-dir
  170.       If non nil generated dokument files will be put into
  171.       this directory. The default is current directory.
  172.  
  173. Skeletons of the major Objective-C constructs are inserted with:
  174.   C-c c class header    C-c m instanceMethod     C-c f factoryMethod
  175.   C-c p protocol        C-c l limiter            C-c h header in h file
  176.   C-c <RET> method comment
  177.  
  178. Other useful stuff
  179.   C-c ? Describe objective-C mode
  180.   C-c a Add signature to use in comments
  181.   C-c v Return the version of this mode
  182.   C-c C-c h Generate an interface file from the implementation file
  183.   C-c C-c d Generate an documentation file from the implementation file
  184.  
  185. Abbreviations:
  186.   ry   & ryes  = return YES
  187.   rn   & rno   = return NO
  188.   rs   & rself = return self
  189.   rnil         = return nil
  190.   imp          = @implementation
  191.   intf         = @interface
  192.   st           = STR
  193.   bo           = BOOL
  194.  
  195. Turning on Objective-C mode calls the value of the variable
  196. objective-C-mode-hook with abbrevs, if that value is non-nil."
  197.   (interactive)
  198.   (kill-all-local-variables)
  199.   (use-local-map objective-C-mode-map)
  200.   (setq major-mode 'objective-C-mode)
  201.   (setq mode-name "Objective-C")
  202.   (setq local-abbrev-table objective-C-mode-abbrev-table)
  203.   (set-syntax-table objective-C-mode-syntax-table)
  204.   (make-local-variable 'paragraph-start)
  205.   (setq paragraph-start (concat "^$\\|" page-delimiter))
  206.   (make-local-variable 'paragraph-separate)
  207.   (setq paragraph-separate paragraph-start)
  208.   (make-local-variable 'indent-line-function)
  209.   (setq indent-line-function 'objective-C-indent-line)
  210.   (make-local-variable 'require-final-newline)
  211.   (setq require-final-newline t)
  212.   (make-local-variable 'comment-start)
  213.   (setq comment-start "/* ")
  214.   (make-local-variable 'signatures)
  215.   (setq signatures nil)
  216.   (make-local-variable 'comment-end)
  217.   (setq comment-end " */")
  218.   (make-local-variable 'comment-column)
  219.   (setq comment-column 32)
  220.   (make-local-variable 'comment-start-skip)
  221.   (setq comment-start-skip "/\\*+ *")
  222.   (make-local-variable 'comment-indent-hook)
  223.   (setq comment-indent-hook 'objective-C-comment-indent)
  224.   (make-local-variable 'parse-sexp-ignore-comments)
  225.   (setq parse-sexp-ignore-comments t)
  226.   (setq objective-C-line-length 70)
  227.   (make-local-variable 'super-filename)
  228.   (setq super-filename nil)
  229.   (run-hooks 'objective-C-mode-hook))
  230.  
  231. ;; ------------------------ EB Stuff ---------------------------
  232.  
  233. ;;--------------- site-init.el --------------- START
  234. (defun eb-day (aString)
  235.   (let ((a
  236.       (car (cdr (assoc aString '((" 1"  "01")
  237.                          (" 2"  "02")
  238.                          (" 3"  "03")
  239.                              (" 4"  "04")
  240.                              (" 5"  "05")
  241.                                  (" 6"  "06")
  242.                                  (" 7"  "07")
  243.                                      (" 8"  "08")
  244.                                      (" 9"  "09")))))))
  245.     (if (null a) aString a)))
  246.  
  247. (defun eb-month (aString)
  248.   (let ((a
  249.       (car (cdr (assoc aString '(("JAN"  "01")
  250.                          ("FEB"  "02")
  251.                          ("MAR"  "03")
  252.                              ("APR"  "04")
  253.                              ("MAY"  "05")
  254.                                  ("JUN"  "06")
  255.                                  ("JUL"  "07")
  256.                                      ("AUG"  "08")
  257.                                      ("SEP"  "09")
  258.                                          ("OCT"  "10")
  259.                                          ("NOV"  "11")
  260.                                              ("DEC"  "12")
  261.                                              ))))))
  262.     (if (null a) aString a)))
  263.  
  264. (defun eb-date ()
  265.   "Return the current date in an EB Signal standard form"
  266.   (concat (substring (current-time-string) -4 nil)
  267.         "-"
  268.           (eb-month (substring (current-time-string) 4 7))
  269.             "-"
  270.           (eb-day (substring (current-time-string) 8 10))))
  271. ;;--------------- site-init.el --------------- END
  272.  
  273. ;; ------------------ File and Class name ------------------------
  274.  
  275. ;; return the type ".m" or ".h" kan be improved
  276. (defun file-type (&optional name)
  277.   (substring (if (null name) (m-filename) name) -2 nil))
  278.  
  279. (defun m-filename ()
  280.   (file-name-nondirectory (file-name-sans-versions buffer-file-name)))
  281.  
  282. (defun is-m-file (&optional name)
  283.   (string-equal ".m" (file-type name)))
  284.  
  285. (defun h-filename ()
  286.   (concat (substring (m-filename) 0 -2) ".h"))
  287.  
  288. (defun h-file-dir ()
  289.   (if (null objective-C-interface-file-dir)
  290.       ""
  291.     objective-C-interface-file-dir))
  292.  
  293. (defun is-h-file (&optional name)
  294.   (string-equal ".h" (file-type name)))
  295.  
  296. (defun doc-filename ()
  297.   (concat (substring (m-filename) 0 -2) ".txt"))
  298.  
  299. (defun doc-dir ()
  300.   (if (null objective-C-document-file-dir)
  301.       ""
  302.     objective-C-document-file-dir))
  303.  
  304. (defun class-from-filename (&optional name)
  305.   (substring (if (null name) (m-filename) name)
  306.               0 (string-match "\\.\\([0-9]*\\.\\)?\\(m\\|h\\|txt\\)"
  307.                        (if (null name) (m-filename) name))))
  308.  
  309. (defun number-from-filename (&optional name)
  310.   (let ((m-file (if (null name) (m-filename) name)))
  311.     (substring m-file
  312.                   (string-match "\\([0-9]*\\)?\\.\\(m\\|h\\)" m-file)
  313.                      (- (length m-file) 2))))
  314.  
  315. ;; Tested and used. Not a very goodlooking
  316. (defun super-class ()
  317.   (let* ((row (concat "@implementation "
  318.                     (class-from-filename)
  319.                       "\\( \\|\t\\|\n\\)*"
  320.                         ":"
  321.                           "\\( \\|\t\\|\n\\)*"))
  322.       (row2 (concat row "[a-zA-Z][a-zA-Z0-9$_]*"))
  323.        (a-list (list (string-match row (buffer-string))
  324.                     (match-end 0)))
  325.         (b-list (list (string-match row2 (buffer-string))
  326.                      (match-end 0))))
  327.     (cond ((null (car a-list)) nil)
  328.         ((null (car b-list)) nil)
  329.           (t (buffer-substring (1+ (cadr a-list))
  330.                           (1+ (cadr b-list)))))))
  331.  
  332. (defun super-class-number ()
  333.   (let ((sc (super-class))
  334.     (no nil))
  335.     (if (null sc) "NO_SUPER_CLASS_FOUND"
  336.       (setq no (read-string (concat "Class number for superclass "
  337.                         (super-class)
  338.                         ": ")))
  339.       (if (string-equal "" no) no
  340.     (concat "." no)))))
  341.  
  342. (defun super-hfilename (&optional number)
  343.   (let ((sc (super-class))
  344.     (no (if (null number) (super-class-number) number)))
  345.     (if (null sc) "NO_SUPER_CLASS_FOUND" (concat sc no ".h"))))
  346.  
  347. ;; ---------------------- AUX ------------------------
  348.  
  349. (defun user-sign ()
  350.   (car (cdr (assoc (user-login-name) signatures))))
  351.  
  352. (defun cadr (l)
  353.   (car (cdr l)))
  354.  
  355. (defun odd (e)
  356.   "True if it's argument is odd."
  357.   (eq (% e 2) 1))
  358.  
  359. (defun e-empty-line-p ()
  360.   "True if current line is empty."
  361.   (save-excursion
  362.     (beginning-of-line)
  363.     (looking-at "^[ \\t]*$")))
  364.  
  365. (defun insert-right (name diff &optional c)
  366.   (let* ((u  (- objective-C-line-length (length name) diff))
  367.       (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  368.     (insert-char fillChar u)
  369.     (insert name)))
  370.  
  371. (defun insert-centered (name diff &optional c)
  372.   "Inserts the name centered in the Objective-C environment
  373. diff is a number that tells how many positions that already
  374. are used on the line (/*     */ = 4) and the optional c
  375. character is used to fill white space with."
  376.   (let* ((toshare  (- objective-C-line-length (length name) diff))
  377.       (u        (/ toshare 2))
  378.        (fillChar (if (char-or-string-p c) c (string-to-char " "))))
  379.     (insert-char fillChar u)
  380.     (insert name)
  381.     (insert-char fillChar (if (odd toshare) (1+ u) u))))
  382.  
  383. (defun add-user-sign ()
  384.   (interactive)
  385.   (let* ((name (user-login-name))
  386.       (sign (read-string (concat "Signature for " name ": "))))
  387.     (setq signatures (cons (list name sign) signatures))))
  388.  
  389. (defun classes-used ()
  390.   "Extract the used classes from the file"
  391.   (save-excursion
  392.     (let ((aString ""))
  393.       (beginning-of-buffer)
  394.       (re-search-forward "Classes used")
  395.       (forward-line 1)
  396.       (while (e-empty-line-p)
  397.     (forward-line 1))
  398.       (beginning-of-line)
  399.       (while (and
  400.                 (not (eobp))
  401.                   (not (e-empty-line-p))
  402.                     (looking-at "#import"))
  403.     (setq aString (concat aString (grep-class-from-line) " "))
  404.     (forward-line 1)
  405.     (beginning-of-line))
  406.       aString)))
  407.  
  408. (defun beginning-of-line-point (&optional aBool)
  409.   (save-excursion
  410.     (beginning-of-line)
  411.     (cond (aBool (skip-chars-forward " \t*/")))
  412.     (point)))
  413.  
  414. (defun end-of-line-point (&optional aBool)
  415.   (save-excursion
  416.     (end-of-line)
  417.     (cond (aBool (skip-chars-backward " \t*/")))
  418.     (point)))
  419.  
  420. (defun grep-class-from-line ()
  421.   (let ((bp (beginning-of-line-point))
  422.     (ep (end-of-line-point)))
  423.     (buffer-substring (+ bp 9) (- ep 3))))
  424.  
  425. (defun start-of-instance-point ()
  426.   (save-excursion
  427.     (beginning-of-buffer)
  428.     (search-forward "@implementation")
  429.     (forward-line 1)
  430.     (while (or (e-empty-line-p)
  431.                   (looking-at "{"))
  432.       (forward-line 1)
  433.       (beginning-of-line))
  434.     (point)))
  435.  
  436. (defun end-of-instance-point ()
  437.   (save-excursion
  438.     (beginning-of-buffer)
  439.     (search-forward "@implementation")
  440.     (search-forward "}")
  441.     (forward-line -1)
  442.     (while (e-empty-line-p)
  443.       (forward-line -1))
  444.     (end-of-line)
  445.     (point)))
  446.  
  447. (defun have-instance-variables ()
  448.   (save-excursion
  449.     (beginning-of-buffer)
  450.     (search-forward "@implementation")
  451.     (forward-line 1)
  452.     (while (e-empty-line-p)      
  453.       (forward-line 1))
  454.     (skip-chars-forward " \t")
  455.     (looking-at "{")))
  456.  
  457. (defun instance-variables ()
  458.   (cond ((have-instance-variables)
  459.       (buffer-substring (start-of-instance-point)
  460.                    (end-of-instance-point)))
  461.     (t "\t // none")))
  462.  
  463. (defun start-of-intro-point ()
  464.   (save-excursion
  465.     (beginning-of-buffer)
  466.     (cond ((null (search-forward "Introduction"
  467.                   (start-of-instance-point)
  468.                    t))
  469.           1)
  470.         (t (forward-line 1)
  471.                 (while (e-empty-line-p)
  472.                      (forward-line 1))
  473.                  (beginning-of-line)
  474.                   (point)))))
  475.  
  476. (defun end-of-intro-point ()
  477.   (save-excursion
  478.     (beginning-of-buffer)
  479.     (cond ((null (search-forward "Revision History"
  480.                   (start-of-instance-point)
  481.                    t))
  482.           1)
  483.         (t (forward-line -1)
  484.                 (while (e-empty-line-p)
  485.                      (forward-line -1))
  486.                  (end-of-line)
  487.                   (point)))))
  488.  
  489. (defun class-intro ()
  490.   (let ((si (start-of-intro-point))
  491.     (ei (end-of-intro-point)))
  492.     (if (or (= si ei) (= si 1) (= ei 1))
  493.     "\tCan't extract the class description since the strings\n\tIntroduction and/or Revision History are missing in the source code."
  494.       (buffer-substring si ei))))
  495.  
  496. (defun find-next-protocol-or-method ()
  497.   (beginning-of-line)
  498.   (while (and (not (eobp))
  499.                 (not (looking-at "/\\*====="))
  500.                   (not (looking-at "+[a-zA-Z( ]"))
  501.                     (not (looking-at "-[a-zA-Z( ]")))
  502.     (forward-line 1)
  503.     (beginning-of-line))
  504.   (cond ((looking-at "/\\*=====")
  505.       (forward-line 1)
  506.        (beginning-of-line)))
  507.   (not (eobp)))
  508.  
  509. (defun line-is-method ()
  510.   (save-excursion
  511.     (beginning-of-line)
  512.     (or (looking-at "+[a-zA-Z( ]")
  513.     (looking-at "-[a-zA-Z( ]"))))
  514.  
  515. (defun line-is-protocol ()
  516.   (save-excursion
  517.     (forward-line -1)
  518.     (beginning-of-line)
  519.     (looking-at "/\\*=====")))
  520.  
  521. (defun is-gps-comment ()
  522.   (save-excursion
  523.     (let ((ordinary (is-ordinary-comment)))
  524.       (beginning-of-line)
  525.       (and (looking-at "---------") ordinary))))
  526.  
  527. (defun is-ordinary-comment ()
  528.   (save-excursion
  529.     (and (char-equal ?* (char-after (- (point) 2)))
  530.       (char-equal ?/ (char-after (- (point) 1)))
  531.        (not (char-equal ?= (char-after (beginning-of-line-point)))))))
  532.  
  533. (defun is-date-entry ()
  534.   (< 50 (- (beginning-of-line-point t) (beginning-of-line-point))))
  535.  
  536. (defun is-method-name-entry ()
  537.   (and (char-equal ?| (char-after (beginning-of-line-point t)))
  538.        (char-equal ?| (char-after (- (end-of-line-point t) 1)))))
  539.  
  540. (defun is-empty-line-info ()
  541.   (string-equal "" (buffer-substring (beginning-of-line-point t)
  542.                           (end-of-line-point))))
  543.  
  544. (defun is-not-crap-line ()
  545.     (and (not (is-date-entry))
  546.       (not (is-method-name-entry))
  547.        (not (is-empty-line-info))))
  548.  
  549. (defun look-for-comment-at-previous-line ()
  550.   (save-excursion
  551.     (forward-line -1)
  552.     (beginning-of-line)
  553.     (skip-chars-forward "\t ")
  554.     (and (char-equal ?/ (char-after (point)))
  555.       (char-equal ?* (char-after (+ (point) 1))))))
  556.  
  557. (defun is-still-comment ()
  558.   (save-excursion
  559.     (beginning-of-line)
  560.     (skip-chars-forward "\t ")
  561.     (if (and (char-equal ?/ (char-after (point)))
  562.               (char-equal ?* (char-after (+ (point) 1))))
  563.     (look-for-comment-at-previous-line)
  564.       t)))
  565.  
  566. (defun is-objc-comment ()
  567.   (save-excursion
  568.     (beginning-of-line)
  569.     (looking-at "//")))
  570.  
  571. (defun gps-comment ()
  572.   (ordinary-comment))
  573.  
  574. (defun ordinary-comment ()
  575.   (let ((aStr ""))
  576.     (forward-line -1)
  577.     (while (is-still-comment)
  578.       (beginning-of-line)
  579.       (skip-chars-forward " \t*/")
  580.       (cond ((is-not-crap-line)
  581.               (setq aStr
  582.                (concat (buffer-substring (point) (end-of-line-point t))
  583.                       "\n"
  584.                          aStr))))
  585.       (forward-line -1))
  586.     aStr))
  587.  
  588. (defun objc-comment ()
  589.   (let ((aStr ""))
  590.     (while (is-objc-comment)
  591.       (beginning-of-line)
  592.       (skip-chars-forward "/ ")
  593.       (cond ((is-not-crap-line)
  594.               (setq aStr
  595.                (concat (buffer-substring (point) (end-of-line-point t))
  596.                       "\n"
  597.                          aStr))))
  598.       (forward-line -1))
  599.     aStr))
  600.  
  601. (defun no-comment ()
  602.   "This method has not been documented in the source code.")
  603.  
  604. (defun line-as-doc-file-delimiter ()
  605.   (save-excursion
  606.     (beginning-of-line)
  607.     (skip-chars-forward " \t")
  608.     (setq start (point))
  609.     (end-of-line)
  610.     (skip-chars-backward " \t")
  611.     (concat "\n" (buffer-substring start (point)) "\n")))
  612.  
  613. (defun line-as-inteface-file-delimiter ()
  614.   (save-excursion
  615.     (beginning-of-line)
  616.     (skip-chars-forward " \t")
  617.     (setq start (point))
  618.     (end-of-line)
  619.     (skip-chars-backward " \t")
  620.     (setq name     (buffer-substring start (point)))
  621.     (setq toshare  (- objective-C-line-length (length name) 8))
  622.     (concat "\n/* "
  623.             (make-string (/ toshare 2) ?-)
  624.             " "
  625.                 (buffer-substring start (point))
  626.                 " "
  627.                     (make-string (if (odd toshare)
  628.                               (+ (/ toshare 2) 1)
  629.                               (/ toshare 2))
  630.                           ?-)
  631.                     " */")))
  632.  
  633. (defun skip-comment (str)
  634.   (let ((p (string-match "//" str)))
  635.     (cond ((null p) str)
  636.         (t (substring str 0 p)))))
  637.  
  638. (defun line-as-inteface-file-method ()
  639.   (save-excursion
  640.     (beginning-of-line)
  641.     (skip-chars-forward " \t")
  642.     (setq start (point))
  643.     (re-search-forward "{")
  644.     (backward-char 1)
  645.     (skip-chars-backward " \t\n")
  646.     (concat (skip-comment (buffer-substring start (point))) ";")))
  647.  
  648. (defun extract-method-comment ()
  649.   (forward-line -1)
  650.   (while (e-empty-line-p)
  651.     (forward-line -1))
  652.   (end-of-line)
  653.   (skip-chars-backward " \t")
  654.   (cond ((is-gps-comment)      (gps-comment))
  655.     ((is-ordinary-comment) (ordinary-comment))
  656.     ((is-objc-comment)     (objc-comment))
  657.     (t                     (no-comment))))
  658.  
  659. (defun method-description (method-name start-point)
  660.   (save-excursion
  661.     (goto-char start-point)
  662.     (concat method-name "\n" (extract-method-comment))))
  663.  
  664. (defun line-as-doc-file-method ()
  665.   (save-excursion
  666.     (beginning-of-line)
  667.     (skip-chars-forward " \t")
  668.     (setq start (point))
  669.     (re-search-forward "{")
  670.     (backward-char 1)
  671.     (skip-chars-backward " \t\n")
  672.     (method-description
  673.      (concat "|" (buffer-substring start (point)) "|") start)))
  674.  
  675. (defun class-as-short ()
  676.   (save-excursion
  677.     (let ((aString ""))
  678.       (beginning-of-buffer)
  679.       (re-search-forward "@implementation")
  680.       (while (and (not (eobp)) (find-next-protocol-or-method))
  681.     (setq aString
  682.                 (concat
  683.                     aString
  684.                        (cond ((line-is-protocol) (line-as-doc-file-delimiter))
  685.                           ((line-is-method)   (line-as-doc-file-method))
  686.                                (t ""))
  687.                           "\n"))
  688.     (forward-line))
  689.       aString)))
  690.  
  691. (defun class-as-short-no-comments ()
  692.   (save-excursion
  693.     (let ((aString ""))
  694.       (beginning-of-buffer)
  695.       (re-search-forward "@implementation")
  696.       (while (and (not (eobp)) (find-next-protocol-or-method))
  697.     (setq aString
  698.                 (concat
  699.                     aString
  700.                        (cond ((line-is-protocol) (line-as-inteface-file-delimiter))
  701.                           ((line-is-method)   (line-as-inteface-file-method))
  702.                                (t ""))
  703.                           "\n"))
  704.     (forward-line))
  705.       aString)))
  706.  
  707. ;; ------------------ Objective-C mode -------------------
  708.  
  709. (defun describe-objective-C-mode ()
  710.   (interactive)
  711.   (describe-mode))
  712.  
  713. (defun objective-C-mfile-header ()
  714.   "Build a class skeleton prompting for class name."
  715.   (interactive)
  716.   (if (not (is-m-file))
  717.       (message "This is not an implementation file (.m)!")
  718.     (let* ((file  (m-filename))
  719.           (class (class-from-filename))
  720.              (nr    (number-from-filename))
  721.             (cname (read-string "Class: " class))
  722.                (super (read-string "Super: ")))
  723.       (if (not (e-empty-line-p))
  724.         (progn (end-of-line)(newline)))
  725.       (indent-to 0)
  726.       (insert "/* ")
  727.       (insert-char ?- (- objective-C-line-length 3))
  728.       (insert "\n\n")
  729.       (insert "\tRDR, Inc. \n\n")
  730.       (insert "\tObjective-C source file for the class " cname "\n\n")
  731.       (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  732.                 ", RDR, Inc.\n")
  733.       (insert "\tALL RIGHTS RESERVED.\n\n")
  734.       (insert "\tResponsible:\t\t\tApproved:\n")
  735.       (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  736.       (insert "\tDate:\t\t\t\tRev:\n")
  737.       (insert "\t" (eb-date)    "\t\t\t___\n\n")
  738. ;      (insert "\tReference:\t\t\tDocument no:\n")
  739. ;      (insert "\tLXA 108 104\t\t\t1/190 55 - CAL 124 1"
  740.                     ;      (if (string-equal "" nr) "***" nr) "\n\n\n\n\n")
  741.       (insert-centered cname 0)
  742.       (insert "\n\n")
  743.       (insert "\t1. Introduction")
  744.       (insert "\n\n\n")
  745.       (insert "\t2. Revision History")
  746.       (insert "\n\n")
  747.       (insert "\t___\tThe starting point.\t\t\t"
  748.                 (user-full-name) "/" (eb-date) "\n\n\n")
  749.       (insert "\t3. Source Code")
  750.       (insert "\n\n")
  751.       (insert-char ?- (- objective-C-line-length 3))
  752.       (insert " */\n\n")
  753.       (comment-line "Import files")
  754.       (insert "#import <appkit/appkit.h>\n\n")
  755.       (comment-line " Classes used ")
  756.       (insert "#import \"foo.h\"\n\n")
  757.       (comment-line " Externals ")
  758.       (insert "\n\n")
  759.       (comment-line " Defines ")
  760.       (insert "\n\n")
  761.       (comment-line " Class variables ")
  762.       (insert "\n\n")
  763.       (comment-box (concat "Implementation of class " cname))
  764.       (insert "#import \"" (concat (substring file 0 -1) "h") "\"\n\n")
  765.       (insert "@implementation " cname " : " super"\n{\n\n}\n\n")
  766.       (comment-box "Instance Creation")
  767.       (insert "\n\n")
  768.       (comment-box "Initialize")
  769.       (insert "\n\n")
  770.       (comment-box "Free")
  771.       (insert "\n\n")
  772.       (insert "@end\n"))
  773.     (re-search-backward "@implementation")
  774.     (next-line 2)
  775.     (objective-C-indent-line)))
  776.  
  777. (defun objective-C-hfile-header (&optional classname super-filename)
  778.   "Gives an interface file sceleton."
  779.   (interactive)
  780.   (if (not (is-h-file))
  781.       (message "This is not an interface file (.h)!")
  782.     (let* ((class (if (null classname) (class-from-filename) classname))
  783.           (cname (read-string "Class: " class))
  784.              (nr    (number-from-filename))
  785.             (super (if (null super-filename)
  786.                          (concat (read-string "Super: ") ".h")
  787.                      super-filename)))
  788.       (insert "/* ")
  789.       (insert-char ?- (- objective-C-line-length 3))
  790.       (insert "\n\n")
  791.       (insert "\tRDR, Inc. \n\n")
  792.       (insert "\tObjective-C interface file for the class " cname "\n\n")
  793.       (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  794.                 ", RDR, Inc.\n")
  795.       (insert "\tALL RIGHTS RESERVED.\n\n")
  796.       (insert "\tResponsible:\t\t\tApproved:\n")
  797.       (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  798.       (insert "\tDate:\t\t\t\tRev:\n")
  799.       (insert "\t" (eb-date)    "\t\t\t___\n\n")
  800.       (insert "\tReference:\t\t\tDocument no:\n")
  801. ;      (insert "\tLXA 108 104\t\t\t2/190 55 - CAL 124 1"
  802.                     ;      (if (string-equal "" nr) "***" nr) "\n\n")
  803. ;      (insert-char ?- (- objective-C-line-length 3))
  804.       (insert " */\n\n")
  805.       (comment-box (concat "Interface of class " cname))
  806.       (insert "#import \"" super "\"\n\n")
  807.       (insert "@interface " cname " : " (class-from-filename super)
  808.                 "\n{\n\n}\n\n")
  809.       (insert "@end\n"))
  810.     (re-search-backward "@interface")
  811.     (next-line 2)
  812.     (objective-C-indent-line)))
  813.  
  814. (defun generate-Objective-C-hfile ()
  815.   "Generate the interface file for the current implementation file."
  816.   (interactive)
  817.   (let* ((file-name (read-string "Interface file name: "
  818.                   (concat (h-file-dir) (h-filename))))
  819.       (buf       (create-file-buffer file-name))
  820.        (class     (class-from-filename))
  821.         (no        (number-from-filename))
  822.          (instance  (instance-variables))
  823.           (short     (class-as-short-no-comments))
  824.            (super     (super-hfilename)))
  825.     (set-buffer buf)
  826.     (set-visited-file-name file-name)
  827.     (insert "/* ")
  828.     (insert-char ?- (- objective-C-line-length 3))
  829.     (insert "\n\n")
  830.     (insert "\tRDR, Inc. \n\n")
  831.     (insert "\tObjective-C interface file for the class " class "\n\n")
  832.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  833.             ", RDR, Inc.\n")
  834.     (insert "\tALL RIGHTS RESERVED.\n\n")
  835.     (insert "\tResponsible:\t\t\tApproved:\n")
  836.     (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  837.     (insert "\tDate:\t\t\t\tRev:\n")
  838.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  839.     (insert "\tReference:\t\t\tDocument no:\n")
  840. ;    (insert "\tLXA 108 104\t\t\t2/190 55 - CAL 124 1"
  841.                     ;    (if (string-equal "" no) "***" no) "\n\n")
  842. ;    (insert-char ?- (- objective-C-line-length 3))
  843.     (insert " */\n\n")
  844.     (comment-box (concat "Interface of class " class))
  845.     (insert "#import \"" super "\"\n\n")
  846.     (insert "@interface " class " : " (class-from-filename super) "\n{\n")
  847.     (insert instance)
  848.     (insert "\n}\n")
  849.     (insert short)
  850.     (insert "\n@end\n")
  851.     (beginning-of-buffer)
  852.     (display-buffer buf)))
  853.  
  854. (defun generate-Objective-C-documentation ()
  855.   "Open a new buffer and write the documentation there."
  856.   (interactive)
  857.   (let* ((file-name (read-string "Documentation file name: "
  858.                   (concat (doc-dir) (doc-filename))))
  859.       (buf       (create-file-buffer file-name))
  860.        (used      (classes-used))
  861.         (class     (class-from-filename))
  862.          (super     (super-class))
  863.           (no        (number-from-filename))
  864.            (instance  (instance-variables))
  865.             (short     (class-as-short))
  866.          (intro     (class-intro)))
  867.     (set-buffer buf)
  868.     (set-visited-file-name file-name)
  869.     (indent-to 0)
  870.     (insert-char ?- objective-C-line-length)
  871.     (insert "\n\n")
  872.     (insert "\tRDR, Inc. \n\n")
  873.     (insert "\tObjective-C documentation file for the class "
  874.             class "\n")
  875.     (insert "\tCOPYRIGHT (C), " (substring  (current-time-string) -4 nil)
  876.             ", RDR, Inc.\n\n")
  877.     (insert "\tResponsible:\t\t\tApproved:\n")
  878.     (insert "\tRDR:" (user-full-name) "\t\t\n\n")
  879.     (insert "\tDate:\t\t\t\tRev:\n")
  880.     (insert "\t" (eb-date)    "\t\t\t___\n\n")
  881.     (insert "\tReference:\t\t\tDocument no:\n")
  882. ;    (insert "\tLXA 108 104\t\t\t1551 - CAL 124 1"
  883. ;            (if (string-equal "" no)
  884.                     ;"***"
  885.                     ;      no) "\n\n")
  886. ;    (insert-char ?- objective-C-line-length)
  887.     (insert "\n\n\n")
  888.     (insert-centered class 0)
  889.     (insert "\n\n\n\tInherits from:\t\t" super "\n\n")
  890.     (insert "\tClasses used:\t\t" used "\n\n")
  891.     (insert "\tInterface file:\t\t" class "." no ".h" "\n\n")
  892.     (insert "\tImplementation file:\t" class "." no ".m" "\n\n\n")
  893.     (insert-centered "Introduction" 0)
  894.     (insert "\n\n")
  895.     (insert intro)
  896.     (insert "\n\n")
  897.     (insert-centered "Instance Variables" 0)
  898.     (insert "\n\n")
  899.     (insert instance)
  900.     (insert "\n\n")
  901.     (insert-centered "Methods" 0)
  902.     (insert "\n")
  903.     (insert short)   
  904.     (insert "\nEnd\n")
  905.     (beginning-of-buffer)
  906.     (display-buffer buf)))
  907.  
  908. (defun comment-box (name)
  909.   "Print name in an comment-box"
  910.   (if (not (e-empty-line-p))
  911.       (progn (end-of-line)(newline)))
  912.   (insert "/*")
  913.   (insert-centered "" 2 ?=)
  914.   (insert "\n")
  915.   (insert-centered name 0 (string-to-char " "))
  916.   (insert "\n")
  917.   (insert-centered "" 2 ?=)
  918.   (insert "*/\n"))
  919.  
  920. (defun comment-line (name)
  921.   "Print name in an comment-line"
  922.   (if (not (e-empty-line-p))
  923.       (progn (end-of-line)(newline)))
  924.   (insert "/* ")
  925.   (insert-centered (concat " " name " ") 6 ?-)
  926.   (insert " */\n"))
  927.  
  928. (defun point-bol ()
  929.   "Returns the value of the point at the beginning of the current line."
  930.   (save-excursion
  931.     (beginning-of-line)
  932.     (point)))
  933.  
  934. (defun within-string-p (point1 point2)
  935.   "Returns true if number of double quotes between two points is odd."
  936.   (let ((s (buffer-substring point1 point2)))
  937.     (not (zerop (mod (count-char-in-string ?\" s) 2)))))
  938.  
  939. (defun count-char-in-string (c s)
  940.   (let ((count 0)
  941.     (pos 0))
  942.     (while (< pos (length s))
  943.       (setq count (+ count (if (\= (aref s pos) c) 1 0)))
  944.       (setq pos (1+ pos)))
  945.     count))
  946.  
  947. (defun objective-C-protocol ()
  948.   "Build a protocol skeleton prompting for protocol name."
  949.   (interactive)
  950.   (comment-box (read-string "Protocol name: ")))
  951.  
  952. (defun objective-C-codelimit ()
  953.   "Print name on a centered line."
  954.   (interactive)
  955.   (comment-line (read-string "Centered text: ")))
  956.  
  957. (defun objective-C-method (prefix name)
  958.   (indent-to 0)
  959.   (insert "/*")
  960.   (insert-centered "" 2 ?-)
  961.   (insert "\n")
  962.   (insert "|" prefix name "| \n" (if (string-equal "-" prefix)
  963.                           "Return self.\n"
  964.                       "\n"))
  965.   (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  966.   (insert "\n")
  967.   (insert-centered "" 2 ?-)
  968.   (insert "*/\n")
  969.   (insert prefix name "\n")
  970.   (insert "{\n")
  971.   (indent-to objective-C-indent-level)
  972.   (if (string-equal "+" prefix)
  973.       (insert "self = [super new];\n")
  974.     (insert "\n"))
  975.   (indent-to objective-C-indent-level)
  976.   (insert "return self;\n")
  977.   (insert "}\n\n")
  978.   (next-line -4))
  979.  
  980. (defun objective-C-method-comment ()
  981.   "Insert a comment according to the style used with methods in GPS"
  982.   (interactive)
  983.   (indent-to 0)
  984.   (insert "/*")
  985.   (insert-centered "" 2 ?-)
  986.   (insert "\n\n\n")
  987.   (insert-right (concat (user-full-name) "/" (eb-date)) 0)
  988.   (insert "\n")
  989.   (insert-centered "" 2 ?-)
  990.   (insert "*/\n"))
  991.  
  992. (defun objective-C-instance-method ()
  993.   "Build a routine skeleton prompting for method name."
  994.   (interactive)
  995.   (if (not (e-empty-line-p))
  996.       (progn (end-of-line)(newline)))
  997.   (objective-C-method "-" (read-string "Instance method name: ")))
  998.  
  999. (defun objective-C-factory-method ()
  1000.   "Build a routine skeleton prompting for method name."
  1001.   (interactive)
  1002.   (if (not (e-empty-line-p))
  1003.       (progn (end-of-line)(newline)))
  1004.   (objective-C-method "+" (read-string "Factory method name: ")))
  1005.  
  1006. ;; ------------------ C- mode fix ---------------------
  1007.  
  1008. ;; This is used by indent-for-comment
  1009. ;; to decide how much to indent a comment in C code
  1010. ;; based on its context.
  1011. (defun objective-C-comment-indent ()
  1012.   (if (looking-at "^\\(/\\*\\|//\\)")
  1013.       0;Existing comment at bol stays there.
  1014.     (save-excursion
  1015.       (skip-chars-backward " \t")
  1016.       (max (1+ (current-column));Else indent at comment column
  1017.        comment-column)))); except leave at least one space.
  1018.  
  1019. ;; implement this function later
  1020. (defun electric-objective-C-keyword-match ()
  1021.   "Match two following lines with keyword arguments"
  1022.   (interactive)
  1023.   (insert ":"))
  1024.  
  1025. (defun electric-objective-C-brace (arg)
  1026.   "Insert character and correct line's indentation."
  1027.   (interactive "P")
  1028.   (let (insertpos)
  1029.     (if (and (not arg)
  1030.               (eolp)
  1031.                (or (save-excursion
  1032.                     (skip-chars-backward " \t")
  1033.                    (bolp))
  1034.                 (if objective-C-auto-newline
  1035.                      (progn (objective-C-indent-line) (newline) t) nil)))
  1036.     (progn
  1037.         (insert last-command-char)
  1038.           (objective-C-indent-line)
  1039.             (if objective-C-auto-newline
  1040.                   (progn
  1041.                 (setq insertpos (1- (point)))
  1042.                 (newline)
  1043.                 (objective-C-indent-line)))
  1044.           (save-excursion
  1045.                 (if insertpos (goto-char (1+ insertpos)))
  1046.                 (delete-char -1))))
  1047.     (if insertpos
  1048.     (save-excursion
  1049.         (goto-char insertpos)
  1050.           (self-insert-command (prefix-numeric-value arg)))
  1051.       (self-insert-command (prefix-numeric-value arg)))))
  1052.  
  1053. (defun electric-objective-C-semi (arg)
  1054.   "Insert character and correct line's indentation."
  1055.   (interactive "P")
  1056.   (if objective-C-auto-newline
  1057.       (electric-objective-C-terminator arg)
  1058.     (self-insert-command (prefix-numeric-value arg))))
  1059.  
  1060. (defun electric-objective-C-terminator (arg)
  1061.   "Insert character and correct line's indentation."
  1062.   (interactive "P")
  1063.   (let (insertpos (end (point)))
  1064.     (if (and (not arg) (eolp)
  1065.               (not (save-excursion
  1066.                  (beginning-of-line)
  1067.                      (skip-chars-forward " \t")
  1068.                      (or (= (following-char) ?#)
  1069.                      ;; Colon is special only after a label, or case ....
  1070.                      ;; So quickly rule out most other uses of colon
  1071.                      ;; and do no indentation for them.
  1072.                      (and (eq last-command-char ?:)
  1073.                                (not (looking-at "case"))
  1074.                                 (save-excursion
  1075.                                      (forward-word 2)
  1076.                                         (<= (point) end)))
  1077.                      (progn
  1078.                          (beginning-of-defun)
  1079.                            (let ((pps (parse-partial-sexp (point) end)))
  1080.                              (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
  1081.     (progn
  1082.         (insert last-command-char)
  1083.           (objective-C-indent-line)
  1084.             (and objective-C-auto-newline
  1085.                     (not (objective-C-inside-parens-p))
  1086.                        (progn
  1087.                       (setq insertpos (1- (point)))
  1088.                        (newline)
  1089.                         (objective-C-indent-line)))
  1090.           (save-excursion
  1091.                 (if insertpos (goto-char (1+ insertpos)))
  1092.                 (delete-char -1))))
  1093.     (if insertpos
  1094.     (save-excursion
  1095.         (goto-char insertpos)
  1096.           (self-insert-command (prefix-numeric-value arg)))
  1097.       (self-insert-command (prefix-numeric-value arg)))))
  1098.  
  1099. (defun objective-C-inside-parens-p ()
  1100.   (condition-case ()
  1101.       (save-excursion
  1102.     (save-restriction
  1103.         (narrow-to-region (point)
  1104.                       (progn (beginning-of-defun) (point)))
  1105.           (goto-char (point-max))
  1106.             (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
  1107.     (error nil)))
  1108.  
  1109. (defun objective-C-indent-command (&optional whole-exp)
  1110.   (interactive "P")
  1111.   "Indent current line as C code, or in some cases insert a tab character.
  1112. If objective-C-tab-always-indent is non-nil (the default), always indent current line.
  1113. Otherwise, indent the current line only if point is at the left margin
  1114. or in the line's indentation; otherwise insert a tab.
  1115.  
  1116. A numeric argument, regardless of its value,
  1117. means indent rigidly all the lines of the expression starting after point
  1118. so that this line becomes properly indented.
  1119. The relative indentation among the lines of the expression are preserved."
  1120.   (if whole-exp
  1121.       ;; If arg, always indent this line as C
  1122.       ;; and shift remaining lines of expression the same amount.
  1123.       (let ((shift-amt (objective-C-indent-line))
  1124.             beg end)
  1125.     (save-excursion
  1126.         (if objective-C-tab-always-indent
  1127.               (beginning-of-line))
  1128.           (setq beg (point))
  1129.             (forward-sexp 1)
  1130.           (setq end (point))
  1131.             (goto-char beg)
  1132.               (forward-line 1)
  1133.                 (setq beg (point)))
  1134.     (if (> end beg)
  1135.             (indent-code-rigidly beg end shift-amt "#")))
  1136.     (if (and (not objective-C-tab-always-indent)
  1137.               (save-excursion
  1138.                    (skip-chars-backward " \t")
  1139.                       (not (bolp))))
  1140.     (insert-tab)
  1141.       (objective-C-indent-line))))
  1142.  
  1143. (defun objective-C-indent-line ()
  1144.   "Indent current line as C code.
  1145. Return the amount the indentation changed by."
  1146.   (let ((indent (calculate-objective-C-indent nil))
  1147.     beg shift-amt
  1148.     (case-fold-search nil)
  1149.     (pos (- (point-max) (point))))
  1150.     (beginning-of-line)
  1151.     (setq beg (point))
  1152.     (cond ((eq indent nil)
  1153.        (setq indent (current-indentation)))
  1154.       ((eq indent t)
  1155.        (setq indent (calculate-objective-C-indent-within-comment)))
  1156.       ((looking-at "[ \t]*#")
  1157.        (setq indent 0))
  1158.       (t
  1159.        (skip-chars-forward " \t")
  1160.        (if (listp indent) (setq indent (car indent)))
  1161.        (cond ((or (looking-at "case\\b") (looking-at "default:"))
  1162.           (setq indent (max 1 (+ indent objective-C-label-offset))))
  1163. ;;
  1164. ;; Hack of the day by dstutz -- labels won't indent right because of it...
  1165. ;;
  1166.          ((and (looking-at "[A-Za-z]")
  1167.             (save-excursion
  1168.               (forward-sexp 1)
  1169.               (looking-at ":")))
  1170.           (save-excursion
  1171.             (forward-line -1)
  1172.             (if (search-forward ":")
  1173.             (progn (forward-sexp -1)
  1174.                    (setq indent (current-column))))))
  1175. ;; Here is the excised code...
  1176. ;;
  1177. ;;       (cond ((or (looking-at "case\\b")
  1178. ;;              (and (looking-at "[A-Za-z]")
  1179. ;;               (save-excursion
  1180. ;;                 (forward-sexp 1)
  1181. ;;                 (looking-at ":"))))
  1182. ;;          (setq indent (max 1 (+ indent objective-C-label-offset))))
  1183. ;;
  1184. ;;
  1185.          ((and (looking-at "else\\b")
  1186.                (not (looking-at "else\\s_")))
  1187.           (setq indent (save-excursion
  1188.                  (objective-C-backward-to-start-of-if)
  1189.                  (current-indentation))))
  1190.          ((= (following-char) ?})
  1191.           (setq indent (- indent objective-C-indent-level)))
  1192.          ((= (following-char) ?{)
  1193.           (setq indent (+ indent objective-C-brace-offset))))))
  1194.     (skip-chars-forward " \t")
  1195.     (setq shift-amt (- indent (current-column)))
  1196.     (if (zerop shift-amt)
  1197.     (if (> (- (point-max) pos) (point))
  1198.             (goto-char (- (point-max) pos)))
  1199.       (delete-region beg (point))
  1200.       (indent-to indent)
  1201.       ;; If initial point was within line's indentation,
  1202.       ;; position after the indentation.  Else stay at same point in text.
  1203.       (if (> (- (point-max) pos) (point))
  1204.         (goto-char (- (point-max) pos))))
  1205.     shift-amt))
  1206.  
  1207. (defun calculate-objective-C-indent (&optional parse-start)
  1208.   "Return appropriate indentation for current line as C code.
  1209. In usual case returns an integer: the column to indent to.
  1210. Returns nil if line starts inside a string, t if in a comment."
  1211.   (save-excursion
  1212.     (beginning-of-line)
  1213.     (let ((indent-point (point))
  1214.       (case-fold-search nil)
  1215.       state
  1216.       containing-sexp)
  1217.       (if parse-start
  1218.       (goto-char parse-start)
  1219.     (beginning-of-defun))
  1220.       (while (< (point) indent-point)
  1221.     (setq parse-start (point))
  1222.     (setq state (parse-partial-sexp (point) indent-point 0))
  1223.     (setq containing-sexp (car (cdr state))))
  1224.       (cond ((or (nth 3 state) (nth 4 state))
  1225.          ;; return nil or t if should not change this line
  1226.          (nth 4 state))
  1227.         ((null containing-sexp)
  1228.          ;; Line is at top level.  May be data or function definition,
  1229.          ;; or may be function argument declaration.
  1230.          ;; Indent like the previous top level line
  1231.          ;; unless that ends in a closeparen without semicolon,
  1232.          ;; in which case this line is the first argument decl.
  1233.          (goto-char indent-point)
  1234.          (skip-chars-forward " \t")
  1235.          (if (= (following-char) ?{)
  1236.          0   ; Unless it starts a function body
  1237.            (objective-C-backward-to-noncomment (or parse-start (point-min)))
  1238.            ;; Look at previous line that's at column 0
  1239.            ;; to determine whether we are in top-level decls
  1240.            ;; or function's arg decls.  Set basic-indent accordingly.
  1241.            (let ((basic-indent
  1242.               (save-excursion
  1243.             (re-search-backward "^[^ \^L\t\n#]" nil 'move)
  1244.             (if (and (looking-at "\\sw\\|\\s_")
  1245.                  (looking-at ".*(")
  1246.                  (progn
  1247.                    (goto-char (1- (match-end 0)))
  1248.                    (forward-sexp 1)
  1249.                    (and (< (point) indent-point)
  1250.                     (not (memq (following-char)
  1251.                            '(?\, ?\;))))))
  1252.                 objective-C-argdecl-indent 0))))
  1253.          
  1254.          ;; Now add a little if this is a continuation line.
  1255.          (+ basic-indent
  1256.             (if(or (bobp)
  1257.                (memq (preceding-char) '(?\) ?\; ?\})))
  1258.             0 0)))))
  1259.         ((/= (char-after containing-sexp) ?{)
  1260.          ;; line is expression, not statement:
  1261.          ;; indent to just after the surrounding open.
  1262.          
  1263.          (goto-char (1+ containing-sexp))
  1264.          (current-column))
  1265.         (t
  1266.          ;; Statement level.  Is it a continuation or a new statement?
  1267.          ;; Find previous non-comment character.
  1268.          (goto-char indent-point)
  1269.          (objective-C-backward-to-noncomment containing-sexp)
  1270.          ;; Back up over label lines, since they don't
  1271.          ;; affect whether our line is a continuation.
  1272.          (while (or (eq (preceding-char) ?\,)
  1273.             (and (eq (preceding-char) ?:)
  1274.                  (or (eq (char-after (- (point) 2)) ?\')
  1275.                  (memq (char-syntax (char-after (- (point) 2)))
  1276.                        '(?w ?_)))))
  1277.            (if (eq (preceding-char) ?\,)
  1278.            (objective-C-backward-to-start-of-continued-exp containing-sexp))
  1279.            (beginning-of-line)
  1280.            (objective-C-backward-to-noncomment containing-sexp))
  1281.          ;; Now we get the answer.
  1282.          (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?\{)))
  1283.          ;; This line is continuation of preceding line's statement;
  1284.          ;; indent  objective-C-continued-statement-offset  more than the
  1285.          ;; previous line of the statement.
  1286.          (progn
  1287.            (objective-C-backward-to-start-of-continued-exp containing-sexp)
  1288.            (+ objective-C-continued-statement-offset (current-column)))
  1289.            ;; This line starts a new statement.
  1290.            ;; Position following last unclosed open.
  1291.            (goto-char containing-sexp)
  1292.            ;; Is line first statement after an open-brace?
  1293.            (or
  1294.         ;; If no, find that first statement and indent like it.
  1295.         (save-excursion
  1296.           (forward-char 1)
  1297.           (let ((colon-line-end 0))
  1298.             (while (progn (skip-chars-forward " \t\n")
  1299.                   (looking-at "#\\|/\\*\\|case[ \t\n].*:\\|[a-zA-Z0-9_$]*:"))
  1300.               ;; Skip over comments and labels following openbrace.
  1301.               (cond ((= (following-char) ?\#)
  1302.                  (forward-line 1))
  1303.                 ((= (following-char) ?\/)
  1304.                  (forward-char 2)
  1305.                  (search-forward "*/" nil 'move))
  1306.                 ;; case or label:
  1307.                 (t
  1308.                  (save-excursion (end-of-line)
  1309.                          (setq colon-line-end (point)))
  1310.                  (search-forward ":"))))
  1311.             ;; The first following code counts
  1312.             ;; if it is before the line we want to indent.
  1313.             (and (< (point) indent-point)
  1314.              (if (> colon-line-end (point))
  1315.                  (- (current-indentation) objective-C-label-offset)
  1316.                (current-column)))))
  1317.         ;; If no previous statement,
  1318.         ;; indent it relative to line brace is on.
  1319.         ;; For open brace in column zero, don't let statement
  1320.         ;; start there too.  If objective-C-indent-offset is zero,
  1321.         ;; use objective-C-brace-offset + objective-C-continued-statement-offset instead.
  1322.         ;; For open-braces not the first thing in a line,
  1323.         ;; add in objective-C-brace-imaginary-offset.
  1324.         (+ (if (and (bolp) (zerop objective-C-indent-level))
  1325.                (+ objective-C-brace-offset objective-C-continued-statement-offset)
  1326.              objective-C-indent-level)
  1327.            ;; Move back over whitespace before the openbrace.
  1328.            ;; If openbrace is not first nonwhite thing on the line,
  1329.            ;; add the objective-C-brace-imaginary-offset.
  1330.            (progn (skip-chars-backward " \t")
  1331.               (if (bolp) 0 objective-C-brace-imaginary-offset))
  1332.            ;; If the openbrace is preceded by a parenthesized exp,
  1333.            ;; move to the beginning of that;
  1334.            ;; possibly a different line
  1335.            (progn
  1336.              (if (eq (preceding-char) ?\))
  1337.              (forward-sexp -1))
  1338.              ;; Get initial indentation of the line we are on.
  1339.              (current-indentation))))))))))
  1340.  
  1341. (defun calculate-objective-C-indent-within-comment ()
  1342.   "Return the indentation amount for line, assuming that
  1343. the current line is to be regarded as part of a block comment."
  1344.   (let (end star-start)
  1345.     (save-excursion
  1346.       (beginning-of-line)
  1347.       (skip-chars-forward " \t")
  1348.       (setq star-start (= (following-char) ?\*))
  1349.       (skip-chars-backward " \t\n")
  1350.       (setq end (point))
  1351.       (beginning-of-line)
  1352.       (skip-chars-forward " \t")
  1353.       (and (re-search-forward "/\\*[ \t]*" end t)
  1354.           star-start
  1355.              (goto-char (1+ (match-beginning 0))))
  1356.       (current-column))))
  1357.  
  1358.  
  1359. ;; Hacked for // style comments ala c++ mode -- dstutz
  1360. (defun objective-C-backward-to-noncomment (lim)
  1361.   (let (opoint stop)
  1362.     (while (not stop)
  1363.       (skip-chars-backward " \t\n\f" lim)
  1364.       (setq opoint (point))
  1365.       (cond ((and (>= (point) (+ 2 lim))
  1366.           (save-excursion
  1367.             (forward-char -2)
  1368.             (looking-at "\\*/")))
  1369.          (search-backward "/*" lim 'move))
  1370.         ((and
  1371.           (search-backward "//" (max (point-bol) lim) 'move)
  1372.           (not (within-string-p (point) opoint))))
  1373.         (t (beginning-of-line)
  1374.            (skip-chars-forward " \t")
  1375.            (if (looking-at "#")
  1376.            (setq stop (<= (point) lim))
  1377.          (setq stop t)
  1378.          (goto-char opoint)))))))
  1379.  
  1380. (defun objective-C-backward-to-start-of-continued-exp (lim)
  1381.   (if (= (preceding-char) ?\))
  1382.       (forward-sexp -1))
  1383.   (beginning-of-line)
  1384.   (if (<= (point) lim)
  1385.       (goto-char (1+ lim)))
  1386.   (skip-chars-forward " \t"))
  1387.  
  1388. (defun objective-C-backward-to-start-of-if (&optional limit)
  1389.   "Move to the start of the last ``unbalanced'' if."
  1390.   (or limit (setq limit (save-excursion (beginning-of-defun) (point))))
  1391.   (let ((if-level 1)
  1392.     (case-fold-search nil))
  1393.     (while (not (zerop if-level))
  1394.       (backward-sexp 1)
  1395.       (cond ((looking-at "else\\b")
  1396.               (setq if-level (1+ if-level)))
  1397.             ((looking-at "if\\b")
  1398.               (setq if-level (1- if-level)))
  1399.             ((< (point) limit)
  1400.                   (setq if-level 0)
  1401.                    (goto-char limit))))))
  1402.  
  1403. (defun mark-objective-C-function ()
  1404.   "Put mark at end of C function, point at beginning."
  1405.   (interactive)
  1406.   (push-mark (point))
  1407.   (end-of-defun)
  1408.   (push-mark (point))
  1409.   (beginning-of-defun)
  1410.   (backward-paragraph))
  1411.